﻿$import( "SmitearWebGL.Resources.Buffer" );

SmitearWebGL.Resources.IndexElementDescription = Class.extend(
{
	init : function( gl, count, offset, type, drawType )
	{
		this._registClass( "SmitearWebGL.Resources.IndexElementDescription" );
		
		count = count == undefined ? 0 : count;
		offset = offset == undefined ? 0 : offset;
		type = type == undefined ? gl.UNSIGNED_SHORT : type;
		drawType = drawType == undefined ? gl.TRIANGLES : drawType;
		
		this.count = count;
		this.offset = offset;
		this.dataType = SmitearWebGL.Resources.Buffer.getGlDataType( gl, type );
		this.drawType = SmitearWebGL.Resources.IndexBuffer.getGlDrawType( gl, drawType );
	}
}
);

SmitearWebGL.Resources.IndexBuffer = SmitearWebGL.Resources.Buffer.extend(
{
	/******** constructor ********/
	
	init : function()
	{
		this._super();
		this._registClass( "SmitearWebGL.Resources.IndexBuffer" );

		/******** public property ********/
		
		/******** private property ********/
		
		this._arrayType = null;
		this._bindType = null;
	}
	,
	createElementDescription : function( count, offset, type, drawType )
	{
		$THROW( this.isResourceCreated(), "该资源还没有被创建." );
		
		if ( ! this._elementDescriptions ) this._elementDescriptions = [];
		
		count = count == undefined ? ( this._glData ? this._glData.length : 0 ) : count;
		
		var desc = new SmitearWebGL.Resources.IndexElementDescription( this.context.gl, count, offset, type, drawType )
		this._elementDescriptions[0] = desc;
		
		return true;
	}
	,
	createSingleStripGrid : function( xVerts, yVerts, xStep, yStep, stride, flags )
	{
		$THROW( this.isResourceCreated(), "该资源还没有被创建." );
		
		var total_strips = yVerts - yStep;
		var total_indexes_per_strip =  xVerts << 1;
		var total_indexes = ( total_indexes_per_strip * total_strips ) + ( total_strips << 1 ) - 2;
		var lineStep = yStep * stride;
		var start_vert = 0, i = 0, j = 0, k = 0;
		var pIndexValues = this.lock( total_indexes );

		for ( j = 0; j < total_strips; ++ j )
		{
			k = 0;
			var vert = start_vert;

			for ( k = 0; k < xVerts; ++ k )
			{
				pIndexValues[i ++ ] = vert;
				pIndexValues[i ++ ] = vert + lineStep;

				vert += xStep;
			}
			start_vert += lineStep;

			if ( j + 1 < total_strips )
			{
				pIndexValues[i ++ ] = ( vert - xStep ) + lineStep;
				pIndexValues[i ++ ] = start_vert;
			}
		}

		this.unlock();
		this.createElementDescription( total_indexes, 0, SmitearWebGL.Resources.Buffer.DataType.UNSIGNED_SHORT, SmitearWebGL.Resources.IndexBuffer.DrawType.TRIANGLE_STRIP );
	}
	,
	draw : function( renderMode )
	{
		$THROW( this.isResourceCreated(), "该资源还没有被创建." );
		
		this.context.gl.drawElements( this._elementDescriptions[0].drawType[renderMode == undefined ? 2 : renderMode],
						this._elementDescriptions[0].count,
						this._elementDescriptions[0].dataType,
						this._elementDescriptions[0].offset );
		
		return SmitearWebGL.Core.HResult.SUCCESS;
	}
	,
	
	/******** private method ********/
	
	_createResource : function()
	{
		this._super();
		
		this._arrayType = Uint16Array;
		this._bindType = this.context.gl.ELEMENT_ARRAY_BUFFER;
	}
}
);

SmitearWebGL.Resources.IndexBuffer.DrawType =
{
	POINT :				0,
	LINE : 				1,
	LINE_STRIP : 		2,
	LINE_LOOP :			3,
	TRIANGLES :			4,
	TRIANGLE_STRIP :	5,
	TRIANGLE_FAN :		6
}
	
SmitearWebGL.Resources.IndexBuffer.getGlDrawType = function( gl, drawType )
{
	switch ( drawType )
	{
		case SmitearWebGL.Resources.IndexBuffer.DrawType.POINT :
			return [gl.POINT,	gl.POINT,		gl.POINT];
		case SmitearWebGL.Resources.IndexBuffer.DrawType.LINE :
			return [gl.POINT,	gl.LINES,		gl.LINES];
		case SmitearWebGL.Resources.IndexBuffer.DrawType.LINE_STRIP :
			return [gl.POINT,	gl.LINE_STRIP,	gl.LINE_STRIP];
		case SmitearWebGL.Resources.IndexBuffer.DrawType.LINE_LOOP :
			return [gl.POINT,	gl.LINE_LOOP,	gl.LINE_LOOP];
		case SmitearWebGL.Resources.IndexBuffer.DrawType.TRIANGLES :
			return [gl.POINT,	gl.LINES,		gl.TRIANGLES];
		case SmitearWebGL.Resources.IndexBuffer.DrawType.TRIANGLE_STRIP :
			return [gl.POINT,	gl.LINE_STRIP,	gl.TRIANGLE_STRIP];
		case SmitearWebGL.Resources.IndexBuffer.DrawType.TRIANGLE_FAN :
			return [gl.POINT,	gl.LINES,		gl.TRIANGLE_FAN];
	}
}